用Python xlwings创建图表

使用VBA和Python xlwings可以通过编程动态绘制Excel图表,本节介绍用Python xlwings包创建Excel图表的几种方法。可以用xlwings包提供的方法直接创建,或者用API方式创建图表工作表,也可以用ChartObjects对象的Add方法,或者用Shapes对象的AddChart2方法进行创建。

Excel对象模型中,用Chart对象表示图表,Charts对象作为集合对所有图表进行保存和管理。通过编程创建图表的过程,就是创建Chart对象并利用它本身及与之相关的一系列对象的属性和方法进行编程的过程。[大谦Excel,dqexcel点com]

用ChartObjects对象创建图表

利用xlwings包提供的ChartObjects对象的Add方法可以创建图表。该方法的语法格式为:

code.python
sht.api.ChartObjects.Add(left=0, top=0, width=355, height=211)

其中,sht表示工作表对象,有4个参数:

• left – 表示图表左侧的位置,单位为点,默认值为0。

• top - 表示图表顶端的位置,单位为点,默认值为0。

• width - 表示图表的宽度,单位为点,默认值为355。

• height – 表示图表的高度,单位位点,默认值为211。

该方法返回一个ChartObject对象,引用该对象的Chart属性返回一个Chart对象。

下面根据给定数据,用ChartObjects对象的Add方法创建图表。完整代码见:Samples->ch03图表基础->01 创建图表:ChartObjects对象->py.py。

code.python
import xlwings as xw    #导入xlwings包
import os    #导入OS包
root=os.getcwd()    #获取当前工作目录
app=xw.App(visible=True, add_book=False)    #创建Excel应用
wb=app.books.open(root+r’/data.xlsx’,read_only=False)    #打开数据文件返回工作簿对象
sht=wb.sheets(‘Sheet1’)    #获取指定工作表对象
cht=sht.api.ChartObjects().Add(50,200,355,211).Chart    #用ChartObjects对象创建图表
cht.SetSourceData(sht.api.Range('A1:H7'),1)    #捆绑数据
cht.ChartType=xw.constants.ChartType.xlColumnClustered    #图表类型
cht.HasTitle=True    #显示图表标题
cht.ChartTitle.Text='部分省市2012-2016年GDP数据'    #标题文本

运行代码,在工作表的指定位置绘制复合柱状图如图2-1所示。

Document Image
\[\]

图2-1 用ChartObjects对象创建图表

利用xlwings包提供的charts对象的add方法可以创建图表,该方法本质上还是使用ChartObjects对象进行创建。该方法的语法格式为:

code.python
sht.charts.add(left=0, top=0, width=355, height=211)

其中,sht表示工作表对象,4个参数表示图表的位置和大小。该方法返回一个chart对象。

本例使用图2-1中相同的数据绘制复合柱状图。完整代码见:Samples->ch03图表基础-> 02 创建图表:xlwings新语法->py.py。

code.python
import xlwings as xw    #导入xlwings包
import os    #导入OS包
root=os.getcwd()    #获取当前工作目录
app=xw.App(visible=True, add_book=False)    #创建Excel应用
wb=app.books.open(root+r’/data.xlsx’,read_only=False)    #打开数据文件返回工作簿对象
sht=wb.sheets(‘Sheet1’)    #获取指定工作表对象
cht=sht.charts.add(50, 200)    #添加图表
cht.set_source_data(sht.range("A1").expand())    #图表绑定数据
cht.chart_type="column_clustered"    #图表类型
cht.api[1].HasTitle=True    #图表有标题
cht.api[1].ChartTitle.Text="部分省市2012-2016年GDP数据"    #标题文本

运行代码生成图2-1。上面代码中,使用charts对象的add方法返回一个表示空白图表的chart对象,图表左上角的位置为(50,200)。用chart对象的set_source_data方法绑定绘图数据。参数中用range对象的expand方法获取单元格A1所在的数据表。用chart_type属性指定图表类型为复合柱状图。最后用API方式指定图表的标题,注意需要设置HasTitle属性的值为True。

用Shapes对象创建图表

用Shapes对象创建图表,实际上也是在xlwings的API使用方式下实现的。在API使用方式下,使用Shapes对象的AddChart2方法创建图表。该方法的语法格式为:

code.python
sht.api.Shapes.AddChart2(Style,XlChartType,Left,Top,Width,Height,NewLayout)

其中,sht为指定工作表。一共有7个参数,均可选。

• Style:图表样式,值为-1时表示各图形类型的默认样式。

• xlChartType:图表类型,值为XlChartType枚举类型,表4-1中列出了一部分。

• Left:图表左侧位置,省略时水平居中。

• Top:图表顶端位置,省略时垂直居中。

• Width:图表的宽度,省略时取默认值354。

• Height:图表的高度,省略时取默认值210。

• NewLayout:表示图表布局,如果值为True,则只有复合图形才会显示图例。

该方法返回一个表示图表的Shape对象,引用该对象的Chart属性返回一个Chart对象。

下面利用图2-1所示工作表中的数据绘制复合柱状图。首先选择数据区域,然后用Shapes对象的AddChart2方法绘制。完整代码见:Samples->ch03图表基础-> 03 创建图表:Shapes对象->py.py。

code.python
import xlwings as xw    #导入xlwings包
import os    #导入OS包
root=os.getcwd()    #获取当前工作目录
app=xw.App(visible=True, add_book=False)    #创建Excel应用
wb=app.books.open(root+r’/data.xlsx’,read_only=False)    #打开数据文件返回工作簿对象
sht=wb.sheets(‘Sheet1’)    #获取指定工作表对象
sht.api.Range("A1").CurrentRegion.Select()    #数据
shp=sht.api.Shapes.AddChart2(-1, xw.constants.ChartType.xlColumnClustered, 200, 20, 350, 250, True)
cht=shp.Chart    #添加图表

生成图2-2所示工作表中下方的图形。

Document Image
\[\]

图2-2 利用Shapes对象绘复合柱状图

通过逐个添加序列创建图表

图2-2所示的复合柱状图中,相同颜色的柱面构成一个序列,相邻的不同颜色的柱面构成一个分组。所以,图2-2所示复合柱状图中有6个序列6个分组。通过编程创建类似图表时,可以使用逐个添加序列的方式进行创建。

下面结合一个实例进行介绍。本例创建包含2个序列的图表,第1个序列的图表类型为柱状图,第2个序列的图表类型为线形图。完整代码见:Samples->ch03图表基础-> 04 创建图表:添加序列->py.py。

code.python
import xlwings as xw    #导入xlwings包
import os    #导入OS包
root=os.getcwd()    #获取当前工作目录
app=xw.App(visible=True, add_book=False)    #创建Excel应用
wb=app.books.open(root+r’/data.xlsx’,read_only=False)    #打开数据文件返回工作簿对象
sht=wb.sheets(‘Sheet1’)    #获取指定工作表对象
sht.api.Range('A2:A7').Select()    #数据
shp=sht.api.Shapes.AddChart2(-1, xw.constants.ChartType.xlColumnClustered, 200, 20, 350, 250, True)
cht=shp.Chart    #添加图表
ser=cht.SeriesCollection().NewSeries()    #添加序列
ser.ChartType=xw.constants.ChartType.xlLine    #序列的图表类型为线形图
ser.Values=sht.api.Range("B2:B7")    #Y轴数据
cht.HasLegend=True    #显示图例

运行代码生成图表如图2-4所示。

Document Image
\[\]

图2-4 逐个添加序列创建图表

创建图表工作表

在API方式下可以创建图表工作表,图表工作表中图表占据整个工作表。通过Charts集合的Add方法可向集合中添加新的图表工作表,Add方法的语法格式为:

code.python
wb.api.Charts.Add(Before,After,Count,Type)

其中,wb表示指定的工作簿对象。该方法的参数都可省略,各参数的含义如下:

• Before - 指定工作表对象,新建的工作表将置于此工作表之前。

• After - 指定工作表对象,新建的工作表将置于此工作表之后。

• Count - 要添加的工作表个数。默认值为1。

• Type - 指定要添加的图表类型。

如果Before和After两者都省略,新建的图表工作表将插入到活动工作表之前。该方法返回一个Chart对象。

下面使用图2-1中相同的数据创建图表工作表,图表类型为复合柱状图。完整代码见:Samples->ch03图表基础->05 创建图表:图表工作表->py.py。

code.python
import xlwings as xw    #导入xlwings包
import os    #导入OS包
root=os.getcwd()    #获取当前工作路径
app=xw.App(visible=True, add_book=False)    #创建Excel应用
wb=app.books.open(root+r’/data.xlsx’,read_only=False)    #打开数据文件返回工作簿对象
sht=wb.sheets(‘Sheet1’)    #获取指定工作表对象
cht=wb.api.Charts.Add()    #创建图表工作表
cht.SetSourceData(Source=sht.api.Range("A1:H7"), PlotBy=1)    #绘图数据
cht.ChartType=xw.constants.ChartType.xlColumnClustered    #图表类型
cht.HasTitle=True    #显示图表标题
cht.ChartTitle.Text='部分省市2012-2016年GDP数据'    #标题文本

运行代码生成图2-3所示的图表工作表。代码中,绑定数据的方式使用的是用Select方法选择数据区域,然后用Charts对象的Add方法创建图表工作表。Add方法返回一个Chart对象,用Chart对象的ChartType属性设置图表类型为复合柱状图。注意指定图表类型常数的方式。最后指定图表的标题。

Document Image
\[\]

图2-3 创建图表工作表

绑定数据

如3.2.2-3.2.4所述,可用三种方法绑定数据。

第一种方法是使用单元格区域的Select方法选择数据。对于工作表sht,使用类似于下面形式的代码进行绑定:

code.python
sht.api.Range("A1").CurrentRegion.Select()

code.python
sht.api.Range("A1:H7").Select()

另一种是使用chart(Chart)对象的set_source_data(SetSourceData)方法绑定数据。

在xlwings使用方式下,使用chart对象的set_source_data方法绑定数据。例如,对于工作表sht和图表cht,使用代码类似于下面的形式:

code.python
cht.set_source_data(sht.range("A1").expand())

该方法只有一个参数,为一range对象,指定数据的范围。

使用API使用方式时,用Chart对象的SetSourceData方法指定图表设置源数据区域。其语法格式如下:

code.python
cht.SetSourceData(Source, PlotBy)

其中,cht为生成的chart对象,有两个参数,含义如下:

• Source - 为一个Range对象,用来指定图表的源数据区域。

• PlotBy - 指定取数据的方式。值为1时表示按列取数据,值为2时表示按行取数据。

对于工作表sht和图表cht,使用代码类似于下面的形式:

code.python
cht.SetSourceData(Source=sht.api.Range("A1:H7"), PlotBy=1)

第三种绑定数据的方式是通过逐个添加序列方式创建图表时,用序列对象的XValues属性指定横轴数据,用Values属性指定纵轴数据。参见3.2.3小节。